# -*- coding: utf-8 -*-

import os
import sys
from contextlib import closing
import math
import jinja2
import hashlib
import time
import werkzeug.utils
import datetime
import openerp
import simplejson
from openerp import http
from openerp.http import request
from openerp.addons.wechat.enterprise import WxApi, WxApplication, WxTextResponse, WxNewsResponse, WxArticle, WxLink
from openerp.addons.website_mshop.pools import ModelPool, CursorProxy, common_functions, PageProxy, _slug
ISODATEFORMAT = '%Y-%m-%d'
ISODATETIMEFORMAT = "%Y-%m-%d %H:%M:%S"
SUPERUSER_ID = 1

if hasattr(sys, 'frozen'):
    # When running on compiled windows binary, we don't have access to package loader.
    path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'html'))
    loader = jinja2.FileSystemLoader(path)
else:
    loader = jinja2.PackageLoader('openerp.addons.dftg_weixin', "html")

env = jinja2.Environment('<%', '%>', '${', '}', '%', loader=loader, autoescape=True)


error_messages = {
    1001: u'验证码不正确',
    1002: u'此手机号码没有提货预定',
    1003: u'预定的提货有错误, 请联系客服',
    1004: u'提货密码有错误, 请核对短信收到的密码',
    1005: u'发送太频繁',
    2001: u'卡券未启用',
    2002: u'卡券未激活',
    2003: u'卡券已兑换',
}


class CardExchangeController(http.Controller):
    weixin_app = None

    def __init__(self):
        env.globals['_pool'] = ModelPool()
        env.globals['_cr'] = CursorProxy()
        env.globals['_page'] = PageProxy()
        env.globals['_slug'] = _slug
        env.globals.update(common_functions)
        env.filters['tojson'] = simplejson.dumps

    def _parse_int(self, parsed_value):
        try:
            parse_value = int(parsed_value)
        except ValueError:
            # TODO 应该需要返回一个错误的response
            raise osv.except_osv(u'错误', u'遇到一个无法解析的id')

        return parse_value

    # 手机号码和卡券密码微信提货页面
    @http.route(['/card/m',
                 '/card/m/partner/<int:partner_id>'], auth='public')
    def card_m_partner_home(self, partner_id=None, **kw):
        send_time = request.session.send_time
        count_down_seconds = 0
        if send_time:
            send_time_diff = (datetime.datetime.now() - request.session.send_time).seconds
            if send_time_diff < 59:
                count_down_seconds = 59 - send_time_diff;

        kw.update({'partner_id': partner_id,
                   'count_down_seconds': count_down_seconds})
        template = env.get_template("card/mobile_index.html")
        return template.render(kw)

    # 取的提货可选的产品列表
    def card_m_get_optional_products(self, card_so_id):
        cr, context, pool = request.cr, request.context, request.registry
        cr.execute("SELECT product_id, product_qty, suite FROM sale_order_card_product WHERE order_id=%s ORDER BY suite" % card_so_id)
        card_product_rows = cr.fetchall()
        product_ids = []
        product_ids_map = {}
        # 遍历关联产品
        for card_product_row in card_product_rows:
            product_id = card_product_row[0]
            product_qty = card_product_row[1]
            suite = card_product_row[2]
            product_ids.append(product_id)
            product_ids_map.setdefault(product_id, {'product_qty': product_qty, 'suite': suite})
        product_rows = pool.get('product.product').browse(cr, 1, product_ids, context=context)

        # 遍历产品行
        product_id_map = {}
        for product in product_rows:
            product_id = product.id
            product_id_map.setdefault(product_id, product)

        # 重新遍历关联产品
        product_suite_list = []
        suite_list = []
        old_suite = None
        for card_product_row in card_product_rows:
            product_id = card_product_row[0]
            product_qty = card_product_row[1]
            suite = card_product_row[2]
            product_ids.append(product_id)

            if old_suite != suite:
                if suite_list:
                    product_suite_list.append(suite_list)
                suite_list = []
            old_suite = suite
            suite_list.append({'product': product_id_map.get(product_id), 'product_qty': product_qty})
        product_suite_list.append(suite_list)
        return product_suite_list

    # 提货记录form页面
    @http.route('/card/m/new', auth='public')
    def card_m_new(self, **kw):
        cr, context, pool = request.cr, request.context, request.registry
        mobile = request.session.mobile
        kw.setdefault('mobile', mobile)
        card_line_id = request.session.card_line_id
        if not card_line_id:
            kw.setdefault('error', u'提货页面已过期, 请回到起始页面重新开始')
        else:
            cr.execute("SELECT so_id FROM product_card_line WHERE id=%s" % card_line_id)
            card_line_row = cr.fetchone()
            card_so_id = card_line_row[0]
            if not card_so_id:
                raise Exception(u'卡券发行有误, 卡券没有关联卡券订单')
            product_suite_list = self.card_m_get_optional_products(card_so_id)
            kw.setdefault('product_suite_list', product_suite_list)
        template = env.get_template("card/mobile_new.html")
        return template.render(kw)

    # 提货记录结果页面
    @http.route('/card/m/info', auth='public')
    def card_m_info(self, **kw):
        cr, context, pool = request.cr, request.context, request.registry
        template = env.get_template("card/mobile_info.html")
        card_line_id = request.session.card_line_id
        if not card_line_id:
            kw.setdefault('error', u'提货页面已过期, 请回到起始页面重新开始')
            return template.render(kw)

        cr.execute("SELECT * FROM product_card_line WHERE id=%s", (card_line_id,))
        card = cr.dictfetchone()
        exchange = {}
        if card and card['is_exchanged']:
            card_code = card['code']
            card_so_id = card['so_id']
            # 取得卡券可选产品列表
            product_suite_list = self.card_m_get_optional_products(card_so_id)
            cr.execute("SELECT * FROM apply_delivery WHERE code=%s", (card_line_id,))
            exchange = cr.dictfetchone()
            if exchange:
                exchange['province_name'] = ''
                exchange['city_name'] = ''
                exchange['county_name'] = ''
                #取得卡券提货订单行产品名称
                if exchange['so_id']:
                    cr.execute("""SELECT pp.id, sol.id as sol_id, socp.id as socp_id, socp.suite,
                    pp.name_template as product_name, sol.product_uom_qty as product_qty, socp.product_outer_name
                    FROM sale_order_line sol
                    INNER JOIN product_product pp ON pp.id=sol.product_id
                    INNER JOIN sale_order so ON so.id=sol.order_id
                    INNER JOIN apply_delivery ad ON ad.so_id=so.id
                    INNER JOIN sale_order_card_product socp ON socp.order_id=so.card_so_id AND socp.product_id=sol.product_id
                    WHERE sol.order_id=%s and ad.suite=socp.suite""", (exchange['so_id'],))
                    products_list = cr.dictfetchall()
                    for product_item in products_list:
                        if product_item.get('product_outer_name'):
                            product_item.update({'product_name': product_item.get('product_outer_name')})
                    exchange['products_list'] = products_list
                #取得省市县名称
                if exchange.get('province_id'):
                    cr.execute('SELECT name FROM res_country_state WHERE id=%s', (exchange['province_id'],))
                    exchange['province_name'] = cr.dictfetchone()['name']
                if exchange.get('city_id'):
                    cr.execute('SELECT city_name FROM all_city WHERE id=%s', (exchange['city_id'],))
                    exchange['city_name'] = cr.dictfetchone()['city_name']
                if exchange.get('county_id'):
                    cr.execute('SELECT county_name FROM all_county WHERE id=%s', (exchange['county_id'],))
                    exchange['county_name'] = cr.dictfetchone()['county_name']
                #如果有货运类型
                if exchange['shipping_type']:
                    cr.execute("SELECT name, description FROM express_type WHERE id=%s", (exchange['shipping_type'],))
                    express_type = cr.dictfetchone()
                    if express_type:
                        exchange['express_type_name'] = express_type['name']
                        exchange['express_type_com'] = express_type['description']
                        #if express_type_code and shipping_code:
                            #调用查询快递接口
                            #self._query_express(express_type_code, shipping_code)

        return template.render(exchange)

    # 根据手机取得未提货的卡券
    def mobile_number_not_exchang(self, mobile):
        cr = request.cr
        # 检查是否有未提货的卡券
        cr.execute("SELECT id FROM product_card_line WHERE mobile='%s' AND is_exchanged=false ORDER BY id" % mobile)
        card_line_row = cr.fetchone()
        if card_line_row:
            return card_line_row[0]

    # 根据手机和密码取得已提货的卡券
    def mobile_number_exchanged(self, mobile, password):
        cr = request.cr
        # 检查是否有未提货的卡券
        cr.execute("SELECT pcl.id FROM product_card_line pcl"
                   " INNER JOIN product_card_password pcp ON pcl.id=pcp.line_id"
                   " WHERE pcl.mobile='%s' AND pcp.password='%s' ORDER BY id" % (mobile, password))
        card_line_row = cr.fetchone()
        if card_line_row:
            return card_line_row[0]

    # 短信发送提货密码
    @http.route('/card/m/send_sms_password', auth='public')
    def card_m_send_sms_password(self, **kw):
        cr = request.cr
        result = {}
        mobile = kw.get('mobile')
        card_line_id = self.mobile_number_not_exchang(mobile)
        if not card_line_id:
            # 此手机号码没有提货预定
            result = {'errcode': 1002, 'errmsg': error_messages.get(1002)}
        else:
            cr.execute("SELECT password FROM product_card_password WHERE line_id=%s" % card_line_id)
            card_password_row = cr.fetchone()
            if not card_password_row:
                # 预定的提货有错误, 请联系客服
                result = {'errcode': 1003, 'errmsg': error_messages.get(1003)}
            else:
                send_time_diff = None
                send_time = request.session.send_time
                if send_time:
                    send_time_diff = (datetime.datetime.now() - request.session.send_time).seconds

                if send_time_diff is not None and send_time_diff < 60:
                    # 短信发送太频繁
                    result = {'errcode': 1005, 'errmsg': error_messages.get(1005), 'errlevel': 'forbidden'}
                else:
                    #发送短信!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                    #发送完成后session里记录发送时间
                    request.session.send_time = datetime.datetime.now()
                    result = {'result': 'OK'}

        return request.make_response(simplejson.dumps(result))

    # 校验提货密码
    @http.route('/card/m/validate/password', auth='public')
    def card_m_validate_password(self, **kw):
        cr, context, pool = request.cr, request.context, request.registry

        result = {}
        mobile = kw.get('mobile')
        password = kw.get('password')
        validate_code = kw.get('validate_code')

        if validate_code != request.session.validate_code:
            # 验证码不正确
            result = {'errcode': 1001, 'errmsg': error_messages.get(1001)}
        else:
            # 取得未提货的卡券
            card_line_id = self.mobile_number_not_exchang(mobile)
            if not card_line_id:
                exchanged_card_line_id = self.mobile_number_exchanged(mobile, password)
                if not exchanged_card_line_id:
                    # 此手机号码没有提货预定
                    result = {'errcode': 1002, 'errmsg': error_messages.get(1002)}
                else:
                    request.session.card_line_id = exchanged_card_line_id
                    result = {'result': 'OK', 'is_exchanged': True}
            else:
                cr.execute("SELECT password FROM product_card_password WHERE line_id=%s" % card_line_id)
                card_password_row = cr.fetchone()
                if not card_password_row:
                    # 预定的提货有错误, 请联系客服
                    result = {'errcode': 1003, 'errmsg': error_messages.get(1003)}
                else:
                    card_password = card_password_row[0]
                    if password != card_password:
                        # 提货密码有错误, 请核对短信收到的密码
                        result = {'errcode': 1004, 'errmsg': error_messages.get(1004)}
                    else:
                        result = {'result': 'OK'}
                        request.session.mobile = mobile
                        request.session.card_line_id = card_line_id

        return request.make_response(simplejson.dumps(result))

    # 检查并返回省市县id
    def card_m_check_ssx(self, ssx):
        cr, context, pool = request.cr, request.context, request.registry
        ssx_list = ssx.split(' ')
        province_name = ssx_list[0]
        city_name = ssx_list[1]
        county_name = ssx_list[2]
        cr.execute("SELECT id FROM res_country_state WHERE name LIKE '%s%%'" % province_name)
        province_row = cr.fetchone()
        if province_row:
            province_id = province_row[0]
            cr.execute("SELECT id FROM all_city WHERE province_id=%s AND city_name LIKE '%s%%'" % (province_id, city_name))
            city_row = cr.fetchone()
            if city_row:
                city_id = city_row[0]
            else:
                values = {'province_id': province_id,
                          'city_name': city_name
                }
                city_id = pool.get('all.city').create(cr, 1, values, context)

            cr.execute("SELECT id FROM all_county WHERE city_id=%s AND county_name LIKE '%s%%'" % (city_id, county_name))
            county_row = cr.fetchone()
            if county_row:
                county_id = county_row[0]
            else:
                values = {'city_id': city_id,
                          'county_name': county_name
                }
                county_id = pool.get('all.county').create(cr, 1, values, context)

            return province_id, city_id, county_id


    # 提货记录保存
    @http.route('/card/m/save', auth='public')
    def card_m_save(self, **kw):
        cr, context, pool = request.cr, request.context, request.registry
        print '-----------kw:', kw
        result = {}
        #从session中取得openid
        openid = request.session.openid
        #从session中取得卡id
        card_line_id = request.session.card_line_id
        cr.execute("SELECT id, code, is_active, is_enabled, is_exchanged, product_id, so_id FROM product_card_line WHERE id=%s", (card_line_id,))
        card = cr.dictfetchone()
        card_code = card['code']
        card_so_id = card['so_id']
        cr.execute('SELECT partner_id, is_multiple_choice_one, state FROM sale_order WHERE id=%s', (card_so_id,))
        sale_order = cr.dictfetchone()
        partner_id = sale_order['partner_id']
        is_multiple_choice_one = sale_order['is_multiple_choice_one']
        #如果卡券编号存在且已激活且已启用且没有兑换
        if card:
            if not card['is_active']:
                # 卡券未启用
                result.update({'errcode': 2001, 'errmsg': error_messages.get(2001)})
                return request.make_response(simplejson.dumps(result))
            if not card['is_active']:
                # 卡券未激活
                result.update({'errcode': 2002, 'errmsg': error_messages.get(2002)})
                return request.make_response(simplejson.dumps(result))
            if card['is_exchanged']:
                # 卡券已兑换
                result.update({'errcode': 2003, 'errmsg': error_messages.get(2003)})
                return request.make_response(simplejson.dumps(result))
            #取得密码
            cr.execute("SELECT password FROM product_card_password WHERE line_id=%s" % (card['id'],))
            password = cr.dictfetchone()['password']
            product_card_track = pool.get('product.card.track')
            apply_delivery = pool.get('apply.delivery')
            #建立兑换记录
            #apply_delivery.create时会自动建立track记录

            province_id, city_id, county_id = self.card_m_check_ssx(kw.get('ssx'))

            #默认预计发货日期为第二天
            delivery_date = datetime.datetime.now() + datetime.timedelta(hours=8) + datetime.timedelta(days=1)
            is_canceled = False
            if sale_order['state'] in ['cancel', 'draft']:
                is_canceled = True
            values = {
                'code': card['id'],
                'copy_code': card_code,
                'password': password,
                'partner_id': partner_id, #对应的卡券订单的客户
                'card_so_id': card_so_id, #对应的卡券订单(很重要, 没有的话会导致修改提货记录套装选项后无法重建提货订单)
                'is_multiple_choice_one': is_multiple_choice_one,
                'province_id': province_id,
                'city_id': city_id,
                'county_id': county_id,
                'address': kw.get('address'),
                'postal_code': kw.get('postal_code'),
                'to_name': kw.get('name'),
                'ship_memo': kw.get('ship_memo'),
                'mobile_number': kw.get('mobile'),
                'phone_number': kw.get('phone'),
                'estimated_ship_date': delivery_date,
                'openid': openid,
                'is_canceled': is_canceled
            }
            suite = kw.get('suite')
            values['suite'] = int(suite)
            apply_delivery_id = apply_delivery.create(cr, SUPERUSER_ID, values, context=context)
            if apply_delivery_id:
                request.session.apply_delivery_id = apply_delivery_id
                result.setdefault('result', 'OK')
        return request.make_response(simplejson.dumps(result))